#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent), ui(new Ui::Widget)
{
    ui->setupUi(this);

    availableDriveList
            << "A:"
            << "B:"
            << "C:"
            << "D:"
            << "E:"
            << "F:"
            << "G:"
            << "H:"
            << "I:"
            << "J:"
            << "K:"
            << "L:"
            << "M:"
            << "N:"
            << "O:"
            << "P:"
            << "Q:"
            << "R:"
            << "S:"
            << "T:"
            << "U:"
            << "V:"
            << "W:"
            << "X:"
            << "Y:"
            << "Z:";

    QFileInfoList extdrivesList = QDir::drives();
    for (int i = 0; i < extdrivesList.size(); ++i)
    {
        QString drive = extdrivesList.at(i).path().toUpper().remove("/");
        availableDriveList.removeAll(drive);
    }

    load();

    ui->comboBoxRecent->addItems(recentList);

    initTrayIcon();

    updateUI();

}

Widget::~Widget()
{
    delete ui;
}

void Widget::on_pushButtonBrowse_clicked()
{
    QString dir = QFileDialog::getExistingDirectory(this, tr("Open Directory"),
                                                    QDir::rootPath(),
                                                    QFileDialog::ShowDirsOnly
                                                    | QFileDialog::DontResolveSymlinks);
    ui->lineEditPath->setText(QDir::toNativeSeparators(dir));
}

void Widget::on_pushButtonRelease_clicked()
{
    QListWidgetItem * item = ui->listWidgetMapped->currentItem();
    if(!item)
    {
        ui->labelResult->setText("nothing to release");
        return;
    }
    QString letter = item->text().left(2).toUpper();
    QStringList arg;
    arg << "/d" << letter;
    if( QProcess::execute("subst", arg) == 0)
    {
        ui->labelResult->setText("release success");
        availableDriveList.append(letter);
        availableDriveList.sort();
        updateUI();
    }
    else
    {
        ui->labelResult->setText("release error");
    }
}

void Widget::on_pushButtonSubst_clicked()
{
    QString path = ui->lineEditPath->text();
    if(0 == path.length())
    {
        ui->labelResult->setText("nothing to subst");
        return;
    }
    QString letter = ui->comboBoxDrive->currentText();
    if(0 == letter.length())
    {
        ui->labelResult->setText("no drive letter available");
        return;
    }
    QStringList arg;
    arg << letter << path;
    if( QProcess::execute("subst", arg) == 0)
    {
        ui->labelResult->setText("subst success");
        availableDriveList.removeAll(letter);
        if(!recentList.contains(path))
            recentList.append(path);
        updateUI();

    }
    else
    {
        ui->labelResult->setText("subst error");
    }
}

void Widget::updateUI()
{
    ui->comboBoxDrive->clear();
    ui->comboBoxDrive->addItems(availableDriveList);

    QProcess proc;
    proc.start("subst");
    proc.waitForStarted();
    proc.closeWriteChannel();
    proc.waitForFinished();

    ui->listWidgetMapped->clear();
    QStringList mapping = QString(proc.readAllStandardOutput()).split("\r\n", QString::SkipEmptyParts);
    ui->listWidgetMapped->addItems(mapping);
    ui->listWidgetMapped->setCurrentRow(0);

    ui->comboBoxRecent->clear();
    ui->comboBoxRecent->addItems(recentList);

    mappedMenu->clear();
    for(int i = 0; i < ui->listWidgetMapped->count(); i++)
    {
        QAction *releaseAction = new QAction(ui->listWidgetMapped->item(i)->text(), this);
        mappedMenu->addAction(releaseAction);
    }

}

void Widget::on_listWidgetMapped_itemDoubleClicked(QListWidgetItem *item)
{
    QString letter = item->text().left(2).toUpper();
    QStringList arg;
    arg << letter;
    QProcess::startDetached("explorer", arg);
}

bool Widget::load()
{
    QFile file("recent.xml");
    file.open(QFile::ReadOnly | QFile::Text);
    reader.setDevice(&file);
    while(!reader.atEnd())
    {
        reader.readNext();
        if(reader.name()=="recent")
        {
            while(!reader.atEnd())
            {
                reader.readNext();
                if(reader.name() == "item")
                {
                    while (!reader.atEnd())
                    {
                        reader.readNext();
                        if (reader.isEndElement())
                            break;
                        if (reader.isStartElement())
                        {
                            recentList.append(reader.readElementText());
                        }
                    }

                }
            }
        }
    }
    return !reader.error();
}

void Widget::save()
{

    QFile file("recent.xml");
    file.open(QFile::WriteOnly | QFile::Text);
    writer.setDevice(&file);
    writer.setAutoFormatting(true);
    writer.writeStartDocument();
    writer.writeStartElement("recent");
    for(int i = 0; i < recentList.size(); i++)
    {
        writer.writeStartElement("item");
        writer.writeTextElement("path", recentList.at(i));
        writer.writeEndElement();
    }
    writer.writeEndElement();
    writer.writeEndDocument();
}

void Widget::closeEvent(QCloseEvent *e)
{
    hide();
    e->ignore();
}

void Widget::on_pushButtonClear_clicked()
{
    recentList.removeAll(ui->comboBoxRecent->currentText());
    updateUI();
}

void Widget::on_comboBoxRecent_activated(const QString &text)
{
    ui->lineEditPath->setText(text);
}

void Widget::initTrayIcon()
{
    quitAction = new QAction(tr("&Quit"), this);
    connect(quitAction, SIGNAL(triggered()), this, SLOT(quitApp()));

    mappedMenu = new QMenu("release: ", this);
    connect(mappedMenu, SIGNAL(triggered(QAction*)), this, SLOT(menuAction(QAction*)));

    trayIconMenu = new QMenu(this);
    trayIconMenu->addMenu(mappedMenu);
    trayIconMenu->addSeparator();
    trayIconMenu->addAction(quitAction);

    trayIcon = new QSystemTrayIcon(this);
    trayIcon->setContextMenu(trayIconMenu);

    connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
            this, SLOT(iconActivated(QSystemTrayIcon::ActivationReason)));

    trayIcon->setIcon(QIcon(":/qsubst.png"));
    trayIcon->show();
}

void Widget::iconActivated(QSystemTrayIcon::ActivationReason reason)
{
    if (reason == QSystemTrayIcon::Trigger){
        if(isVisible())
            hide();
        else
        {
            showNormal();
        }
    }
}

void Widget::quitApp()
{
    save();
    qApp->quit();
}

void Widget::menuAction(QAction * action)
{
    QString letter = action->text().left(2).toUpper();
    QStringList arg;
    arg << "/d" << letter;
    if( QProcess::execute("subst", arg) == 0)
    {
        ui->labelResult->setText("release success");
        availableDriveList.append(letter);
        availableDriveList.sort();
        updateUI();
    }
}
